﻿//<TunynetCopyright>
//--------------------------------------------------------------
//<copyright>青岛拓宇网络科技有限公司 2005-2008</copyright>
//<version>V0.5</verion>
//<createdate>2008-2-21</createdate>
//<author>mazq</author>
//<email>mazq@tunynet.com</email>
//<log date="2008-2-21">创建</log>
//--------------------------------------------------------------
//</TunynetCopyright>

using System;
using System.Collections.Generic;
using System.Text;
using System.Workflow.Runtime;
using System.Workflow.ComponentModel;
using ChinaCustoms.Qingdao.Workflow.Supports;
using System.Xml;
using System.Configuration;
using System.IO;
using System.Web;

namespace ChinaCustoms.Qingdao.Workflow.Activities
{
    /// <summary>
    /// 工作流帮助器
    /// </summary>
    public class WorkflowHelper
    {
        /////<overloads>获取工作流的活动原型数据</overloads>
        ///// <summary>
        ///// 获取工作流的活动原型数据
        ///// </summary>
        ///// <param name="workflowType">工作流的<see cref="Type"/>类型</param>
        ///// <param name="workflowGuid">工作流实例Guid</param>
        ///// <returns>工作流所有活动原型数据</returns>
        //public static List<ActivityPrototypeInfo> GetActivityPrototypesFromWorkflow(Type workflowType, Guid workflowGuid)
        //{
        //    WorkflowRuntime runtime = new WorkflowRuntime();
        //    WorkflowInstance instance = runtime.CreateWorkflow(workflowType);

        //    List<ActivityPrototypeInfo> activityPrototypeInfos = new List<ActivityPrototypeInfo>();
        //    GetChildActivities(activityPrototypeInfos, instance.GetWorkflowDefinition(), workflowGuid);

        //    //if (activityPrototypeInfos != null && activityPrototypeInfos.Count > 0)
        //    //{
        //    //    activityPrototypeInfos[0].IsFirstActivityPrototype = true;
        //    //    activityPrototypeInfos[activityPrototypeInfos.Count - 1].IsLastActivityPrototype = true;
        //    //}
        //    return activityPrototypeInfos;
        //}

        ///// <summary>
        ///// 获取工作流的活动原型数据
        ///// </summary>
        ///// <param name="workflowType">工作流定义文件的<see cref="XmlReader"/></param>
        ///// <param name="workflowGuid">工作流实例Guid</param>
        ///// <returns>工作流所有活动原型数据</returns>
        //public static List<ActivityPrototypeInfo> GetActivityPrototypesFromWorkflow(XmlReader workflowDefinitionReader, Guid workflowGuid)
        //{
        //    WorkflowRuntime runtime = new WorkflowRuntime();
        //    WorkflowInstance instance = runtime.CreateWorkflow(workflowDefinitionReader);

        //    List<ActivityPrototypeInfo> activityPrototypeInfos = new List<ActivityPrototypeInfo>();
        //    GetChildActivities(activityPrototypeInfos, instance.GetWorkflowDefinition(), workflowGuid);

        //    //if (activityPrototypeInfos != null && activityPrototypeInfos.Count > 0)
        //    //{
        //    //    activityPrototypeInfos[0].IsFirstActivityPrototype = true;
        //    //    activityPrototypeInfos[activityPrototypeInfos.Count - 1].IsLastActivityPrototype = true;
        //    //}
        //    return activityPrototypeInfos;
        //}


        //private static void GetChildActivities(List<ActivityPrototypeInfo> activityInstanceInfos, Activity activity, Guid workflowGuid)
        //{
        //    if (activity is CompositeActivity)
        //    {
        //        CompositeActivity compositeActivity = activity as CompositeActivity;

        //        foreach (Activity temp in compositeActivity.Activities)
        //        {
        //            GetChildActivities(activityInstanceInfos, temp, workflowGuid);
        //        }
        //    }
        //    else
        //    {
        //        CommonActivity commonActivity = activity as CommonActivity;
        //        if (commonActivity != null)
        //        {
        //            ActivityPrototypeInfo info = new ActivityPrototypeInfo();
        //            info.WorkflowGuid = workflowGuid;
        //            info.ActivityName = commonActivity.Name;
        //            info.CodeName = commonActivity.CodeName;
        //            info.ActivityLevel = commonActivity.ActivityLevel;

        //            if (!string.IsNullOrEmpty(commonActivity.Description))
        //                info.Description = commonActivity.Description;

        //            if (!string.IsNullOrEmpty(commonActivity.UrlOfWorkItem))
        //                info.UrlOfWorkItem = commonActivity.UrlOfWorkItem;

        //            info.IsSubFlow = false;

        //            if (!string.IsNullOrEmpty(commonActivity.ActivityCodeNamesForJump))
        //                info.ActivityCodeNamesForJump = commonActivity.ActivityCodeNamesForJump;

        //            info.AllowBack = commonActivity.AllowBack;

        //            //info.AllowAttachment = commonActivity.AllowAttachment;
        //            info.AllowFinalJudgment = commonActivity.AllowFinalJudgment;
        //            info.AllowPostil = commonActivity.AllowPostil;
        //            info.AllowRedesignateExecutor = commonActivity.AllowRedesignateExecutor;

        //            if (!string.IsNullOrEmpty(commonActivity.RequiredDepartmentIDs))
        //                info.RequiredDepartmentIDs = commonActivity.RequiredDepartmentIDs;

        //            info.RequiredRelativeDepartment = commonActivity.RequiredRelativeDepartment;

        //            if (!string.IsNullOrEmpty(commonActivity.RequiredRoles))
        //                info.RequiredRoles = commonActivity.RequiredRoles;

        //            if (!string.IsNullOrEmpty(commonActivity.RequiredUserNames))
        //                info.RequiredUserNames = commonActivity.RequiredUserNames;

        //            activityInstanceInfos.Add(info);
        //        }

        //        SubFlowActivity subFlowActivity = activity as SubFlowActivity;
        //        if (subFlowActivity != null)
        //        {
        //            ActivityPrototypeInfo info = new ActivityPrototypeInfo();
        //            info.WorkflowGuid = workflowGuid;
        //            info.ActivityName = subFlowActivity.Name;
        //            info.CodeName = subFlowActivity.CodeName;
        //            info.ActivityLevel = subFlowActivity.ActivityLevel;
        //            info.Description = subFlowActivity.Description;

        //            if (!string.IsNullOrEmpty(subFlowActivity.UrlOfWorkItem))
        //                info.UrlOfWorkItem = subFlowActivity.UrlOfWorkItem;

        //            info.IsSubFlow = true;



        //            if (!string.IsNullOrEmpty(subFlowActivity.RequiredDepartmentIDs))
        //                info.RequiredDepartmentIDs = subFlowActivity.RequiredDepartmentIDs;


        //            info.OnlyShowRelativeTopLevelInOrganizationSelectorOfSubFlow = subFlowActivity.OnlyShowRelativeTopLevelInOrganizationSelectorOfSubFlow;

        //            activityInstanceInfos.Add(info);
        //        }
        //    }
        //}


        /// <summary>
        /// 解析并把活动原型存储到数据库
        /// </summary>
        /// <param name="workflowDefinitionReader">工作流定义文件的<see cref="XmlReader"/></param>
        /// <param name="workflowGuid">工作流实例Guid</param>
        /// <returns>工作流所有活动原型数据</returns>
        public static void ParseAndSaveWorkflow(string workflowXmlFile, Guid workflowGuid)
        {
            string workflowXmlFileFullPath = string.Empty;
            string workflowFilePath = ConfigurationManager.AppSettings["WorkflowFilePath"];

            // Make sure it isn't a drive reference like "c:\filepath" or a UNC name like "\\machine\share"
            if ((workflowFilePath.IndexOf(":\\") != -1) || (workflowFilePath.IndexOf("\\\\") != -1))
                workflowXmlFileFullPath = Path.Combine(workflowFilePath, workflowXmlFile);
            else
                workflowXmlFileFullPath = HttpContext.Current.Server.MapPath(workflowFilePath + workflowXmlFile);

            XmlReader workflowXmlReader = XmlReader.Create(workflowXmlFileFullPath);
            WorkflowRuntime runtime = new WorkflowRuntime();
            WorkflowInstance instance = runtime.CreateWorkflow(workflowXmlReader);
            workflowXmlReader.Close();

            ParseAndSaveChildActivities(instance.GetWorkflowDefinition(), workflowGuid, Guid.Empty);
        }


        /// <summary>
        /// 解析并把活动原型存储到数据库
        /// </summary>
        /// <param name="activity">活动实例</param>
        /// <param name="workflowGuid">工作流实例ID</param>
        /// <param name="subFlowGuid">子流程ID</param>
        private static void ParseAndSaveChildActivities(Activity activity, Guid workflowGuid, Guid subFlowGuid)
        {
            if (activity is CompositeActivity)
            {
                CompositeActivity compositeActivity = activity as CompositeActivity;
                foreach (Activity temp in compositeActivity.Activities)
                {
                    ParseAndSaveChildActivities(temp, workflowGuid, subFlowGuid);
                }
            }
            else
            {
                CommonActivity commonActivity = activity as CommonActivity;
                if (commonActivity != null)
                {
                    ActivityPrototypeInfo activityPrototypeInfo = new ActivityPrototypeInfo();
                    activityPrototypeInfo.PrototypeGuid = Guid.NewGuid();
                    activityPrototypeInfo.WorkflowGuid = workflowGuid;
                    activityPrototypeInfo.SubFlowGuid = subFlowGuid;
                    activityPrototypeInfo.ActivityName = commonActivity.Name;
                    activityPrototypeInfo.CodeName = commonActivity.CodeName;
                    activityPrototypeInfo.ActivityLevel = commonActivity.ActivityLevel;

                    if (!string.IsNullOrEmpty(commonActivity.Description))
                        activityPrototypeInfo.Description = commonActivity.Description;

                    if (!string.IsNullOrEmpty(commonActivity.UrlOfWorkItem))
                        activityPrototypeInfo.UrlOfWorkItem = commonActivity.UrlOfWorkItem;

                    activityPrototypeInfo.IsSubFlow = false;

                    if (!string.IsNullOrEmpty(commonActivity.ActivityCodeNamesForJump))
                        activityPrototypeInfo.ActivityCodeNamesForJump = commonActivity.ActivityCodeNamesForJump;

                    activityPrototypeInfo.AllowBack = commonActivity.AllowBack;

                    //info.AllowAttachment = commonActivity.AllowAttachment;
                    activityPrototypeInfo.AllowFinalJudgment = commonActivity.AllowFinalJudgment;
                    activityPrototypeInfo.AllowPostil = commonActivity.AllowPostil;
                    activityPrototypeInfo.AllowRedesignateExecutor = commonActivity.AllowRedesignateExecutor;

                    if (!string.IsNullOrEmpty(commonActivity.RequiredDepartmentIDs))
                        activityPrototypeInfo.RequiredDepartmentIDs = commonActivity.RequiredDepartmentIDs;

                    activityPrototypeInfo.RequiredRelativeDepartment = commonActivity.RequiredRelativeDepartment;

                    if (!string.IsNullOrEmpty(commonActivity.RequiredRoles))
                        activityPrototypeInfo.RequiredRoles = commonActivity.RequiredRoles;

                    if (!string.IsNullOrEmpty(commonActivity.RequiredUserNames))
                        activityPrototypeInfo.RequiredUserNames = commonActivity.RequiredUserNames;

                    ActivityPrototypes.CreateActivityPrototype(activityPrototypeInfo);
                }
                else
                {
                    SubFlowActivity subFlowActivity = activity as SubFlowActivity;
                    if (subFlowActivity != null && string.IsNullOrEmpty(subFlowActivity.SubFlowXmlFile)==false)
                    {
                        ActivityPrototypeInfo activityPrototypeInfo = new ActivityPrototypeInfo();
                        activityPrototypeInfo.PrototypeGuid = Guid.NewGuid();
                        activityPrototypeInfo.WorkflowGuid = workflowGuid;
                        activityPrototypeInfo.SubFlowGuid = subFlowGuid;
                        activityPrototypeInfo.ActivityName = subFlowActivity.Name;
                        activityPrototypeInfo.CodeName = subFlowActivity.CodeName;
                        activityPrototypeInfo.ActivityLevel = subFlowActivity.ActivityLevel;
                        activityPrototypeInfo.Description = subFlowActivity.Description;

                        if (!string.IsNullOrEmpty(subFlowActivity.UrlOfWorkItem))
                            activityPrototypeInfo.UrlOfWorkItem = subFlowActivity.UrlOfWorkItem;

                        activityPrototypeInfo.IsSubFlow = true;

                        activityPrototypeInfo.AllowBack = false;
                        activityPrototypeInfo.AllowPostil = false;
                        activityPrototypeInfo.AllowFinalJudgment = false;

                        if (!string.IsNullOrEmpty(subFlowActivity.RequiredDepartmentIDs))
                            activityPrototypeInfo.RequiredDepartmentIDs = subFlowActivity.RequiredDepartmentIDs;

                        activityPrototypeInfo.OnlyShowRelativeTopLevelInOrganizationSelectorOfSubFlow = subFlowActivity.OnlyShowRelativeTopLevelInOrganizationSelectorOfSubFlow;

                        //info.SubFlowXmlFile = subFlowActivity.SubFlowXmlFile;
                        activityPrototypeInfo.RequireFeedbackInSubFlow = subFlowActivity.RequireFeedback;
                        activityPrototypeInfo.StartSubFlowAndStopThisFlow = subFlowActivity.StartSubFlowAndStopThisFlow;


                        SubFlowInfo subFlowInfo = new SubFlowInfo();
                        subFlowInfo.SubFlowGuid = Guid.NewGuid();
                        subFlowInfo.ActivityPrototypeGuid = activityPrototypeInfo.PrototypeGuid;
                        subFlowInfo.WorkflowGuid = workflowGuid;
                        subFlowInfo.SubFlowName = activityPrototypeInfo.ActivityName;

                        activityPrototypeInfo.CorrelativeSubFlowGuid = subFlowInfo.SubFlowGuid;
                        ActivityPrototypes.CreateActivityPrototype(activityPrototypeInfo);
                        SubFlows.CreateSubFlow(subFlowInfo);

                        string workflowXmlFileFullPath = string.Empty;
                        string workflowFilePath = ConfigurationManager.AppSettings["WorkflowFilePath"];


                        // Make sure it isn't a drive reference like "c:\filepath" or a UNC name like "\\machine\share"
                        if ((workflowFilePath.IndexOf(":\\") != -1) || (workflowFilePath.IndexOf("\\\\") != -1))
                        {
                            workflowXmlFileFullPath = Path.Combine(workflowFilePath, subFlowActivity.SubFlowXmlFile);
                        }
                        else
                        {
                            workflowXmlFileFullPath = HttpContext.Current.Server.MapPath(workflowFilePath + subFlowActivity.SubFlowXmlFile);
                        }

                        XmlReader workflowXmlReader = XmlReader.Create(workflowXmlFileFullPath);
                        WorkflowRuntime runtime = new WorkflowRuntime();
                        WorkflowInstance instance = runtime.CreateWorkflow(workflowXmlReader);
                        workflowXmlReader.Close();

                        ParseAndSaveChildActivities(instance.GetWorkflowDefinition(), workflowGuid, subFlowInfo.SubFlowGuid);
                    }
                }
            }
        }



    }
}
